package com.example.hfweather.util

import android.content.Context
import android.content.SharedPreferences
import com.example.hfweather.WeatherApplication
import com.example.hfweather.bean.CityData
import com.google.common.reflect.TypeToken
import com.google.gson.Gson
import androidx.core.content.edit


object FavoriteManager {
    // 定义SharedPreferences文件的名称
    private const val PREFS_NAME = "city_favorite_prefs"

    // 定义用于存储收藏城市的键名
    private const val FAVORITE_PREFIX = "favorites_"

    // 延迟初始化SharedPreferences对象
    private lateinit var sharedPreferences: SharedPreferences

    // 初始化Gson对象用于JSON序列化和反序列化
    private val gson = Gson()

    /**
     * 初始化SharedPreferences对象
     * @param context 应用上下文环境
     */
    fun init(context: Context) {
        // 获取或创建SharedPreferences对象
        sharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
    }

    // 获取当前用户的收藏键(token)
    private fun getCurrentUserKey(): String? {
        // 1. 从Application中获取当前用户信息
        val user = WeatherApplication.user.username
        return "$FAVORITE_PREFIX$user"
    }

    /**
     * 添加城市到收藏列表
     * @param cityData 要添加的城市数据
     */
    fun addFavorite(cityData: CityData) {
        val userKey = getCurrentUserKey() ?: return
        val currentSet = getFavoritesForUser(userKey).toMutableSet()
        currentSet.remove(cityData) // 移除同名旧数据
        currentSet.add(cityData)
        saveFavoritesForUser(userKey, currentSet)
    }

    /**
     * 从收藏列表中移除城市
     * @param cityName 要移除的城市名称
     */
    fun removeFavorite(cityName: String) {
        val userKey = getCurrentUserKey() ?: return
        val currentSet = getFavoritesForUser(userKey).toMutableSet()
        val tempCity = CityData(cityName, 0.0, 0.0, "", "")
        currentSet.remove(tempCity)
        saveFavoritesForUser(userKey, currentSet)
    }

    /**
     * 切换城市收藏状态
     * @param cityData 城市数据
     * @return 返回切换后的收藏状态
     */
    fun toggleFavorite(cityData: CityData): Boolean {
        val userKey = getCurrentUserKey() ?: return false
        val currentSet = getFavoritesForUser(userKey).toMutableSet()
        val tempCity = CityData(cityData.name, 0.0, 0.0, "", "")
        val isFavorite = currentSet.contains(tempCity)

        if (isFavorite) {
            currentSet.remove(tempCity)
        } else {
            currentSet.add(cityData)
        }

        saveFavoritesForUser(userKey, currentSet)
        return !isFavorite
    }

    /**
     * 检查城市是否在收藏列表中
     * @param cityName 要检查的城市名称
     * @return 返回布尔值表示收藏状态
     */
    fun isFavorite(cityName: String): Boolean {
        val userKey = getCurrentUserKey() ?: return false
        val tempCity = CityData(cityName, 0.0, 0.0, "", "")
        return getFavoritesForUser(userKey).contains(tempCity)
    }

    fun getCurrentUserFavorites(): Set<CityData> {
        val userKey = getCurrentUserKey() ?: return emptySet()
        return getFavoritesForUser(userKey)
    }

    /**
     * 根据用户key获取收藏城市集合
     * @param userKey 用户标识
     * @return 返回解析后的城市集合
     */
    private fun getFavoritesForUser(userKey: String): Set<CityData> {
        // 从SharedPreferences获取原始字符串集合
        val jsonSet = sharedPreferences.getStringSet(userKey, mutableSetOf()) ?: return emptySet()

        return try {
            // 如果集合为空，直接返回空集合
            if (jsonSet.isEmpty()) {
                emptySet()
            } else {
                // 使用TypeToken获取目标类型信息
                val type = object : TypeToken<Set<CityData>>() {}.type
                // 使用Gson将字符串转换为CityData对象集合
                gson.fromJson(jsonSet.toString(), type) ?: emptySet()
            }
        } catch (e: Exception) {
            // 出现异常时返回空集合
            emptySet()
        }
    }

    /**
     * 保存用户收藏的城市集合到SharedPreferences
     * @param userKey 用户标识
     * @param cities 城市数据集合
     */
    private fun saveFavoritesForUser(userKey: String, cities: Set<CityData>) {
        // 将CityData对象集合转换为JSON字符串集合
        val jsonSet = cities.map { gson.toJson(it) }.toSet()
        // 使用SharedPreferences编辑器保存数据
        sharedPreferences.edit {
            putStringSet(userKey, jsonSet)
            apply()
        }
    }

    /**
     * 更新已收藏的城市信息
     * @param cityData 新的城市数据
     */
    fun updateFavorite(cityData: CityData) {
        val userKey = getCurrentUserKey() ?: return
        if (isFavorite(cityData.name)) {
            addFavorite(cityData)
        }
    }

}